package cn.bluech.lib.auth;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;

import java.io.File;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import cn.bluech.lib.utils.ByteUtils;
import cn.bluech.lib.utils.StreamUtils;

/**
 * App签名工具类
 *   getSignatureDigest(new File(Environment.getExternalStorageDirectory(),
 *                         "AuthorityTool.apk"),SignUtils.TYPE_MD5);
 *   getSignatureDigest(this,SignUtils.TYPE_MD5);
 */
public class SignUtils {
    public static final String TYPE_MD5    = "MD5";
    public static final String TYPE_SHA1   = "SHA1";
    public static final String TYPE_SHA256 = "SHA256";

    /**
     * 生成摘要信息
     * @param bytes 原签名数据
     * @param algorithm 算法(MD5/SHA1/SHA256)
     */
    private static String digest(byte[] bytes, String algorithm) {
        try {
            MessageDigest digest = MessageDigest.getInstance(algorithm);
            return ByteUtils.toHex(digest.digest(bytes),":");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 获取已经安装的 app 的签名信息
     */
    public static byte[] getSignature(Context ctx, String pkgName) {
        try {
            PackageInfo packageInfo = ctx.getPackageManager().getPackageInfo(
                    pkgName, PackageManager.GET_SIGNING_CERTIFICATES);
            Signature[] signs = packageInfo.signingInfo.getApkContentsSigners();
            return signs[0].toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] getSignature(Context ctx) {
        return getSignature(ctx,ctx.getPackageName());
    }

    public static String getSignatureDigest(Context ctx, String pkgName, String type) {
        return digest(getSignature(ctx,pkgName), type);
    }

    public static String getSignatureDigest(Context ctx, String type) {
        return digest(getSignature(ctx), type);
    }

    public static String getSignatureDigest(Context ctx) {
        return digest(getSignature(ctx), TYPE_MD5);
    }

    /**
     * 加载签名
     * 要读完后getCertificates()才有值
     */
    private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je) {
        InputStream is = null;
        try {
            byte[] buf = new byte[8192];
            is = jarFile.getInputStream(je);
            while (is.read(buf) != -1); // 应该是解压的动作
            return je.getCertificates();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            StreamUtils.close(is);
        }
        return null;
    }

    /**
     * 从APK文件中读取签名
     */
    public static byte[] getSignature(File apkFile) {
        try {
            JarFile jarFile = new JarFile(apkFile);
            JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
            Certificate[] certs = loadCertificates(jarFile, je);
            return null!=certs?certs[0].getEncoded():null;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String getSignatureDigest(File apkFile, String type){
        return digest(getSignature(apkFile), type);
    }

    public static String getSignatureDigest(File apkFile){
        return digest(getSignature(apkFile), TYPE_MD5);
    }
}
